import 'dart:io';

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_list_view/flutter_list_view.dart';
import 'package:jingyuan/PlayerManager/index.dart';
import 'package:jingyuan/commmon/FavoriteMgr.dart';
import 'package:jingyuan/commmon/Opencc.dart';
import 'package:oktoast/oktoast.dart';

typedef TMainTabListOnPlayCallback = Function(Map<String, dynamic> item);
typedef TMainTabListOnSearchCallback = Function(List<int> result);

class MainTabListController extends ChangeNotifier {
  int actionMode = -1;

  String strToSearch = "";

  search(String str) {
    strToSearch = str;
    actionMode = 0;
    notifyListeners();
  }

  int direction = 0;
  playNext(int d) {
    if (d > 0) {
      direction = 1;
    } else if (d < 0) {
      direction = -1;
    } else {
      direction = 0;
    }
    actionMode = 1;
    notifyListeners();
  }

  int jumpIndex = -1;
  jumpPos(int pos) {
    actionMode = 2;
    jumpIndex = pos;
    notifyListeners();
  }

  int nextSearchDirection = -1;
  goNextSearchResult(int direction) {
    actionMode = 3;
    nextSearchDirection = direction;
    notifyListeners();
  }
}

class MainTabList extends StatefulWidget {
  MainTabList(
      {super.key,
      required this.datas,
      this.cb,
      this.searchCb,
      this.controller,
      required this.playerManager});

  final List<dynamic> datas;
  MainTabListController? controller;
  TMainTabListOnPlayCallback? cb;
  TMainTabListOnSearchCallback? searchCb;
  PlayerManager playerManager;

  @override
  State<MainTabList> createState() => _MainTabListState();
}

class _MainTabListState extends State<MainTabList> {
  FlutterListViewController _flutterListViewController = FlutterListViewController();
  bool _searching = false;
  final double _itemHeight = 40;
  List<int> _searchResult = [];
  int _searchResultCursor = -1;

  bool _isFirstLoadForJump = true;

  String get currPlayingUrl {
    if (widget.playerManager.currItem != null) {
      return widget.playerManager.currItem!["url"];
    }
    return "";
  }

  bool get isPlaying {
    return widget.playerManager.isPlaying;
  }

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((mag) {
      if (_isFirstLoadForJump) {
        onJumpCurrentPos();
        _isFirstLoadForJump = false;
      }
    });

    if (widget.controller != null) {
      widget.controller!.addListener(() {
        if (widget.controller!.actionMode == 0) {
          _searching = false;
          if (widget.controller!.strToSearch != null && widget.controller!.strToSearch.isNotEmpty) {
            _searching = true;
          }
          _searchResult.clear();
          _searchResultCursor = 0;
          if (_searching) {
            int i = 0;
            bool firstMatched = true;
            var strToSearchSimple = Opencc.t2s(widget.controller!.strToSearch, false);
            var strToSearchTr = Opencc.s2t(widget.controller!.strToSearch, false);

            for (var element in widget.datas) {
              var name = element["url"];
              if (name != null &&
                  (name.contains(strToSearchSimple) || name.contains(strToSearchTr))) {
                if (firstMatched) jumpToIndex(i);
                firstMatched = false;
                _searchResult.add(i);
              }
              ++i;
            }
          }
          if (widget.searchCb != null) widget.searchCb!(_searchResult);
        } else if (widget.controller!.actionMode == 1) {
          if (widget.controller!.direction != 0) {
            if (widget.playerManager.currItem != null) {
              var foundPos = getCurrPlayingPos();
              if (foundPos != -1) {
                foundPos += widget.controller!.direction;
                if (foundPos < 0) {
                  showToast("沒有更多了~");
                  return; // 到开头，也不再播放了
                }
                if (foundPos >= widget.datas.length) {
                  showToast("沒有更多了~");
                  return; // 到结尾，就不再播放了
                }
                onItemPlay(foundPos);
              }
            }
          }
        } else if (widget.controller!.actionMode == 2) {
          if (widget.controller!.jumpIndex == -1) {
            onJumpCurrentPos();
          } else {
            jumpToIndex(widget.controller!.jumpIndex);
          }
        } else if (widget.controller!.actionMode == 3) {
          if (_searchResult.isEmpty) return;
          if (widget.controller!.nextSearchDirection == 1) {
            _searchResultCursor = (_searchResultCursor + 1) % _searchResult.length;
            jumpToIndex(_searchResult[_searchResultCursor]);
          } else {
            --_searchResultCursor;
            if (_searchResultCursor < 0) _searchResultCursor = _searchResult.length - 1;
            jumpToIndex(_searchResult[_searchResultCursor]);
          }
        }

        setState(() {});
      });
    }
  }

  int getJumpCurrPos() {
    if (widget.playerManager.currItem == null) return 0;
    var url = widget.playerManager.currItem!["url"];
    var foundPos = widget.datas.indexWhere((element) {
      var temp = element as Map<String, dynamic>;
      var theUrl = temp["url"];
      return url == theUrl;
    });
    return foundPos;
  }

  int getCurrPlayingPos() {
    if (widget.playerManager.currItem == null) return 0;
    var url = widget.playerManager.currItem!["url"];
    return getItemIndex(url);
  }

  int getItemIndex(String url) {
    var foundPos = widget.datas.indexWhere((element) {
      var temp = element as Map<String, dynamic>;
      var theUrl = temp["url"];
      return url == theUrl;
    });
    return foundPos;
  }

  onItemPlay(int index) {
    if (widget.cb != null) {
      widget.cb!(widget.datas[index] as Map<String, dynamic>);
    }
  }

  onJumpCurrentPos() {
    int pos = getJumpCurrPos();
    jumpToIndex(pos);
  }

  jumpToIndex(int index) {
    if (index < 0) {
      showToast("跳轉失敗~");
      return;
    }
    _flutterListViewController.animateTo(index * _itemHeight,
        curve: Curves.bounceIn, duration: const Duration(milliseconds: 200));
  }

  @override
  Widget build(BuildContext context) {
    return NotificationListener(
      onNotification: (notification) {
        // FocusScope.of(context).requestFocus(FocusNode());
        return true;
      },
      child: FlutterListView(
          controller: _flutterListViewController,
          delegate: FlutterListViewDelegate((context, index) {
            var temp = widget.datas[index % widget.datas.length];
            var url = temp["url"];
            var name = temp["name"];
            var isItemPlaying = currPlayingUrl == url;
            var trueIndex = index;
            var isItemFavourited = FavoriteMgr.getInstance().isItemIn(trueIndex);
            var isSearchMatched = false;
            if (_searching) {
              isSearchMatched = _searchResult.contains(index);
            }
            return Container(
                padding: const EdgeInsets.only(left: 2, right: 8),
                height: _itemHeight,
                color: isSearchMatched ? Colors.lightGreen : Colors.transparent,
                child: Row(children: [
                  IconButton(
                      onPressed: () {
                        onItemPlay(index);
                      },
                      color: isItemPlaying ? Colors.blue : Colors.black12,
                      icon: Icon(
                          isPlaying && isItemPlaying ? Icons.pause_outlined : Icons.play_arrow)),
                  Expanded(
                      child: GestureDetector(
                          onDoubleTap: () {
                            onItemPlay(index);
                          },
                          child: Text(
                            '${index + 1}. $name',
                            style: TextStyle(
                                overflow: TextOverflow.ellipsis,
                                color: isItemPlaying ? Colors.blue : Colors.black),
                          ))),
                  IconButton(
                      onPressed: () {
                        if (isItemFavourited) {
                          FavoriteMgr.getInstance().remove(trueIndex);
                        } else {
                          FavoriteMgr.getInstance().add(trueIndex);
                        }
                        isItemFavourited = !isItemFavourited;
                        setState(() {});
                      },
                      color: isItemFavourited ? Colors.blue : Colors.black12,
                      icon: Icon(isItemFavourited
                          ? Icons.favorite_outlined
                          : Icons.favorite_border_outlined))
                ]));
          }, childCount: widget.datas.length, preferItemHeight: _itemHeight)),
    );
  }
}
